package com.keqiang.chart.utils

import android.graphics.*
import kotlin.math.acos
import kotlin.math.cos
import kotlin.math.sin

/*
 * 画布绘制方法扩展
 * Created by wanggaowan on 2022/8/24 13:51
 */

/**
 * 绘制3D矩形,向上绘制
 *
 * @param startX 3D矩形左下角底部顶点X坐标
 * @param startY 3D矩形左下角底部顶点Y坐标
 * @param length 3D矩形的长
 * @param width 3D矩形的宽
 * @param height 3D矩形的高
 * @param color 3D矩形颜色
 * @param faceDegrees 3D矩形正面相对于用户的顺时针旋转角度，设置0则只能看到两个面(顶部和正面)，大于0则能看到三个面(顶部、正面和右侧面)
 */
@Suppress("UnnecessaryVariable")
fun Canvas.draw3DRectangle(paint: Paint, startX: Float, startY: Float, length: Float, width: Float, height: Float,
                           color: Int, faceDegrees: Float = 30f) {
    // 计算3D柱形图的七个坐标点
    // 第一面
    val x1 = startX
    val y1 = startY

    val x2 = startX + length
    val y2 = y1

    val x3 = x2
    val y3 = startY - height

    val x4 = x1
    val y4 = y3

    // 第二面(顶部)
    val faceRadian = faceDegrees.toRadian
    val x5 = x4 + width * cos(faceRadian)
    val y5 = y4 - width * sin(faceRadian)

    val x6 = x3 + width * cos(faceRadian)
    val y6 = y3 - width * sin(faceRadian)

    // 第三面(右边)
    val x7 = x2 + width * cos(faceRadian)
    val y7 = y2 - width * sin(faceRadian)

    paint.style = Paint.Style.FILL
    paint.color = color
    val tempPath = ObjectPool.obtainPath()
    tempPath.reset()
    tempPath.moveTo(x1, y1)
    tempPath.lineTo(x2, y2)
    tempPath.lineTo(x3, y3)
    tempPath.lineTo(x4, y4)
    drawPath(tempPath, paint)

    tempPath.reset()
    tempPath.moveTo(x4, y4)
    tempPath.lineTo(x3, y3)
    tempPath.lineTo(x6, y6)
    tempPath.lineTo(x5, y5)
    drawPath(tempPath, paint)

    tempPath.reset()
    tempPath.moveTo(x2, y2)
    tempPath.lineTo(x7, y7)
    tempPath.lineTo(x6, y6)
    tempPath.lineTo(x3, y3)
    drawPath(tempPath, paint)

    paint.color = Color.WHITE
    paint.style = Paint.Style.STROKE
    paint.strokeWidth = 0.5f
    drawLine(x2, y2, x3, y3, paint)
    drawLine(x3, y3, x6, y6, paint)
    drawLine(x3, y3, x4, y4, paint)

    ObjectPool.recyclePath(tempPath)
}

/**
 * 绘制底部扇形(3D饼状图底部构成部分)，绘制方向为从下往上绘制。
 *
 * 调用方法链为：[draw3DArcShadow],drawTop置为true -> [draw3DArcBottom]->[draw3DArcShadow]->[draw3DArcTop]
 *
 * @param cx 底部扇形的圆心X坐标
 * @param cy 底部扇形的圆心Y坐标
 * @param height 3D扇形的高度
 * @param flipAngle 翻转角度，0°则和二维饼状图一致，90°则只能看到一个二维矩形.允许取值范围为0°~90°
 * @param startAngle 扇形起始角度
 * @param sweepAngle 扇形角度
 * @param sliceSpace 各扇形直接的间隙，如果[sweepAngle] >= 360°，则此属性无效，如果动画绘制且最终绘制一个完整的圆，此值请传0，否则可能出现非预期错误
 */
fun Canvas.draw3DArcBottom(paint: Paint, cx: Float, cy: Float, radius: Float, innerRadius: Float, height: Float, flipAngle: Float,
                           startAngle: Float, sweepAngle: Float, color: Int, dx: Float = 0f, dy: Float = 0f, sliceSpace: Float = 0f) {
    if (sweepAngle <= 0 || height <= 0) {
        return
    }

    val shadowColor = setColorLuminance(color, 0.9f)
    draw3DArcShadow(paint, cx, cy, innerRadius, height, flipAngle, startAngle, sweepAngle,
        setColorLuminance(color, 0.88f), dx, dy, sliceSpace, false)

    val draw =
        drawArc(paint, cx, cy, radius, flipAngle, innerRadius, startAngle, sweepAngle, shadowColor, dx, dy, sliceSpace)
    if (!draw) {
        return
    }

    if (sweepAngle < 360) {
        drawArcSide(paint, cx, cy, radius, innerRadius, height,
            flipAngle, startAngle, sweepAngle, shadowColor, dx, dy, sliceSpace)
    }

    draw3DArcShadow(paint, cx, cy, innerRadius, height, flipAngle, startAngle, sweepAngle,
        setColorLuminance(color, 0.88f), dx, dy, sliceSpace, true)
}

/**
 * 绘制3D扇形侧面矩形
 */
private fun Canvas.drawArcSide(paint: Paint, cx: Float, cy: Float, radius: Float, innerRadius: Float, height: Float, flipAngle: Float,
                               startAngle: Float, sweepAngle: Float, color: Int, dx: Float = 0f, dy: Float = 0f, sliceSpace: Float = 0f) {
    val tempPathMeasure = ObjectPool.obtainPathMeasure()
    val tempFloatArray = ObjectPool.obtainFloatArray()
    val tempPath = ObjectPool.obtainPath()

    // 求startAngle过圆心的直线平移sliceSpace / 2f后与圆的交点，得出交点与圆心连线的角度
    var addedDegrees = 90f - acos(sliceSpace / 2f / radius).toDegrees
    // 计算扇形之间的间隙导致中心点偏移的半径
    val offsetRadius = sliceSpace / 2f / sin(sweepAngle.toRadian / 2f)
    var start = (startAngle + addedDegrees).to360Range
    var sweep = sweepAngle - addedDegrees * 2
    var centerX = cx + dx
    var centerY = cy + dy * cos(flipAngle.toRadian)
    // 椭圆短轴半径
    var radiusShort = radius * cos(flipAngle.toRadian)
    val offsetX = cos((startAngle + sweepAngle / 2f).toRadian) * offsetRadius
    val offsetY =
        sin((startAngle + sweepAngle / 2f).toRadian) * offsetRadius * cos(flipAngle.toRadian)

    paint.color = color
    // 需要设置画笔样式为FILL_AND_STROKE且stroke宽度为1px，否则可能出现侧面矩形与上下两个圆结合时存在缝隙
    paint.style = Paint.Style.FILL_AND_STROKE
    paint.strokeWidth = 1f
    if (innerRadius == 0f) {
        tempPath.reset()
        createOvalPath(tempPath, centerX, centerY, radius, radiusShort, start, sweep)
        tempPathMeasure.setPath(tempPath, false)
        if (tempPathMeasure.length == 0f) {
            ObjectPool.recyclePath(tempPath)
            ObjectPool.recyclePathMeasure(tempPathMeasure)
            ObjectPool.recycleFloatArray(tempFloatArray)
            return
        }

        // 计算偏移后的中心点
        centerX += offsetX
        centerY += offsetY
        // 绘制开始角度的侧面
        tempPath.reset()
        tempPath.moveTo(centerX, centerY)
        tempPath.lineTo(centerX, centerY - height)
        tempPathMeasure.getPosTan(0f, tempFloatArray, null)
        tempPath.lineTo(tempFloatArray[0], tempFloatArray[1] - height)
        tempPath.lineTo(tempFloatArray[0], tempFloatArray[1])
        drawPath(tempPath, paint)

        // 绘制结束角度的侧面
        tempPath.reset()
        tempPath.moveTo(centerX, centerY)
        tempPath.lineTo(centerX, centerY - height)
        tempPathMeasure.getPosTan(tempPathMeasure.length, tempFloatArray, null)
        tempPath.lineTo(tempFloatArray[0], tempFloatArray[1] - height)
        tempPath.lineTo(tempFloatArray[0], tempFloatArray[1])
        drawPath(tempPath, paint)
    } else {
        tempPath.reset()
        createOvalPath(tempPath, centerX, centerY, radius, radiusShort, start, sweep)
        tempPathMeasure.setPath(tempPath, false)
        if (tempPathMeasure.length == 0f) {
            ObjectPool.recyclePath(tempPath)
            ObjectPool.recyclePathMeasure(tempPathMeasure)
            ObjectPool.recycleFloatArray(tempFloatArray)
            return
        }

        tempPathMeasure.getPosTan(0f, tempFloatArray, null)
        val x1 = tempFloatArray[0]
        val y1 = tempFloatArray[1]
        tempPathMeasure.getPosTan(tempPathMeasure.length, tempFloatArray, null)
        val x2 = tempFloatArray[0]
        val y2 = tempFloatArray[1]

        // 内圆起始点坐标
        val x3: Float
        val y3: Float
        // 内圆结束点坐标
        val x4: Float
        val y4: Float

        // 求startAngle过圆心的直线平移sliceSpace / 2f后与圆的交点，得出交点与圆心连线的角度
        addedDegrees = 90f - acos(sliceSpace / 2f / innerRadius).toDegrees
        if (addedDegrees * 2 >= sweepAngle) {
            // 说明扇形中心点在内圆半径之外
            x3 = centerX + offsetX
            y3 = centerY + offsetY
            x4 = centerX + offsetX
            y4 = centerY + offsetY
        } else {
            start = (startAngle + addedDegrees).to360Range
            sweep = sweepAngle - addedDegrees * 2
            radiusShort = innerRadius * cos(flipAngle.toRadian)

            tempPath.reset()
            createOvalPath(tempPath, centerX, centerY, innerRadius, radiusShort, start, sweep)
            tempPathMeasure.setPath(tempPath, false)
            if (tempPathMeasure.length == 0f) {
                ObjectPool.recyclePath(tempPath)
                ObjectPool.recyclePathMeasure(tempPathMeasure)
                ObjectPool.recycleFloatArray(tempFloatArray)
                return
            }

            tempPathMeasure.getPosTan(0f, tempFloatArray, null)
            x3 = tempFloatArray[0]
            y3 = tempFloatArray[1]
            tempPathMeasure.getPosTan(tempPathMeasure.length, tempFloatArray, null)
            x4 = tempFloatArray[0]
            y4 = tempFloatArray[1]
        }

        // 绘制开始角度的侧面
        tempPath.reset()
        tempPath.moveTo(x1, y1)
        tempPath.lineTo(x1, y1 - height)
        tempPath.lineTo(x3, y3 - height)
        tempPath.lineTo(x3, y3)
        drawPath(tempPath, paint)

        // 绘制结束角度的侧面
        tempPath.reset()
        tempPath.moveTo(x2, y2)
        tempPath.lineTo(x2, y2 - height)
        tempPath.lineTo(x4, y4 - height)
        tempPath.lineTo(x4, y4)
        drawPath(tempPath, paint)
    }

    ObjectPool.recyclePath(tempPath)
    ObjectPool.recyclePathMeasure(tempPathMeasure)
    ObjectPool.recycleFloatArray(tempFloatArray)
}

/**
 * 根据绘制的扇形覆盖角度，创建不同的路径
 */
private fun createOvalPath(path: Path, centerX: Float, centerY: Float, radius: Float, radiusShort: Float, startAngle: Float, sweepAngle: Float) {
    if (sweepAngle < 360) {
        path.arcTo(centerX - radius, centerY - radiusShort, centerX + radius, centerY + radiusShort,
            startAngle, sweepAngle, false)
    } else {
        path.addOval(centerX - radius, centerY - radiusShort, centerX + radius, centerY + radiusShort, Path.Direction.CW)
    }
}

/**
 * 绘制底部扇形与顶部扇形之间的阴影内容(3D饼状图中间构成部分)，绘制方向为从下往上绘制
 *
 * @param cx 底部扇形的圆心X坐标
 * @param cy 底部扇形的圆心Y坐标
 * @param height 3D扇形的高度
 * @param flipAngle 翻转角度，0°则和二维饼状图一致，90°则只能看到一个二维矩形.允许取值范围为0°~90°
 * @param startAngle 扇形起始角度
 * @param sweepAngle 扇形角度
 * @param sliceSpace 各扇形直接的间隙，如果[sweepAngle] >= 360°，则此属性无效，如果动画绘制且最终绘制一个完整的圆，此值请传0，否则可能出现非预期错误
 * @param drawTop true 表示绘制内环上半部分阴影， false 表示绘制外环下半部分阴影
 */
fun Canvas.draw3DArcShadow(paint: Paint, cx: Float, cy: Float, radius: Float, height: Float, flipAngle: Float, startAngle: Float,
                           sweepAngle: Float, color: Int, dx: Float = 0f, dy: Float = 0f, sliceSpace: Float = 0f, drawTop: Boolean = false) {
    if (sweepAngle <= 0 || height <= 0) {
        return
    }

    var addedDegrees = 0f
    if (sweepAngle < 360) {
        // 求startAngle过圆心的直线平移sliceSpace / 2f后与圆的交点，得出交点与圆心连线的角度
        addedDegrees = 90f - acos(sliceSpace / 2f / radius).toDegrees
        if (addedDegrees * 2 >= sweepAngle) {
            return
        }

        // 沿着偏移夹角的中轴线进行偏移
        // 计算扇形之间的间隙导致中心点偏移的半径
        val offsetRadius = sliceSpace / 2f / sin(sweepAngle.toRadian / 2f)
        if (offsetRadius >= radius && sweepAngle <= 30) {
            // 间隙挤压导致饼状图不可见, 当sweepAngle趋近360°时，offsetRadius >= radius也会成立，
            // 因此还要求sweepAngle <= 30，一般情况下都是sweepAngle趋近0°时才会使offsetRadius >= radius成立
            return
        }
    }

    val start = (startAngle + addedDegrees).to360Range
    val sweep = sweepAngle - addedDegrees * 2
    val end = start + sweep

    val centerX = cx + dx
    val centerY = cy + dy * cos(flipAngle.toRadian)
    // 椭圆短轴半径
    val radiusShort = radius * cos(flipAngle.toRadian)

    val tempPath = ObjectPool.obtainPath()
    val tempPathMeasure = ObjectPool.obtainPathMeasure()
    val tempFloatArray = ObjectPool.obtainFloatArray()

    // 绘制上下扇形之间的阴影，只需要绘制矩形框即可，视觉上看起就是连贯的
    paint.color = color
    // 需要设置画笔样式为FILL_AND_STROKE且stroke宽度为1px，否则可能出现阴影矩形与上下两个圆结合时存在缝隙
    paint.style = Paint.Style.FILL_AND_STROKE
    paint.strokeWidth = 1f

    if (start <= 180) {
        if (!drawTop) {
            drawShadow(paint, tempPath, tempPathMeasure, tempFloatArray, centerX, centerY, radius, radiusShort, height,
                start, if (end > 180) 180f - start else end - start)

            if (end > 360f) {
                drawShadow(paint, tempPath, tempPathMeasure, tempFloatArray, centerX, centerY, radius, radiusShort, height,
                    360f, end - 360f)
            }
        }

        if (drawTop) {
            if (end > 180) {
                drawShadow(paint, tempPath, tempPathMeasure, tempFloatArray, centerX, centerY, radius, radiusShort, height,
                    180f, if (end > 360) 180f else end - 180f)
            }
        }
    } else {
        if (drawTop) {
            drawShadow(paint, tempPath, tempPathMeasure, tempFloatArray, centerX, centerY, radius, radiusShort, height,
                start, if (end > 360) 360f - start else end - start)

            if (end > 540f) {
                drawShadow(paint, tempPath, tempPathMeasure, tempFloatArray, centerX, centerY, radius, radiusShort, height,
                    540f, end - 540f)
            }
        }

        if (!drawTop) {
            if (end > 360f) {
                drawShadow(paint, tempPath, tempPathMeasure, tempFloatArray, centerX, centerY, radius, radiusShort, height,
                    360f, if (end > 540f) 180f else end - 360f)
            }
        }
    }

    ObjectPool.recyclePath(tempPath)
    ObjectPool.recyclePathMeasure(tempPathMeasure)
    ObjectPool.recycleFloatArray(tempFloatArray)
}

/**
 * 绘制阴影扇形
 */
private fun Canvas.drawShadow(paint: Paint, path: Path, pathMeasure: PathMeasure, floatArray: FloatArray, centerX: Float, centerY: Float,
                              radius: Float, radiusShort: Float, height: Float, startAngle: Float, sweepAngle: Float) {
    path.reset()
    createOvalPath(path, centerX, centerY, radius, radiusShort, startAngle, sweepAngle)
    pathMeasure.setPath(path, false)
    if (pathMeasure.length == 0f) {
        return
    }

    path.reset()
    pathMeasure.getPosTan(0f, floatArray, null)
    path.moveTo(floatArray[0], floatArray[1])
    path.arcTo(centerX - radius, centerY - radiusShort, centerX + radius, centerY + radiusShort, startAngle, sweepAngle, false)

    pathMeasure.getPosTan(pathMeasure.length, floatArray, null)
    if (pathMeasure.length == 0f) {
        return
    }

    path.lineTo(floatArray[0], floatArray[1] - height)
    path.arcTo(centerX - radius, centerY - radiusShort - height, centerX + radius, centerY + radiusShort - height, startAngle + sweepAngle, -sweepAngle, false)

    drawPath(path, paint)
}

/**
 * 绘制顶部扇形(3D饼状图顶部构成部分)。
 *
 * 调用方法链为：[draw3DArcShadow],drawTop置为true -> [draw3DArcBottom]->[draw3DArcShadow]->[draw3DArcTop]
 *
 * @param cx 顶部扇形的圆心X坐标
 * @param cy 顶部扇形的圆心Y坐标
 * @param flipAngle 翻转角度，0°则和二维饼状图一致，90°则只能看到一个二维矩形.允许取值范围为0°~90°
 * @param startAngle 扇形起始角度
 * @param sweepAngle 扇形角度
 * @param sliceSpace @param sliceSpace 各扇形直接的间隙，如果[sweepAngle] >= 360°，则此属性无效，如果动画绘制且最终绘制一个完整的圆，此值请传0，否则可能出现非预期错误
 */
fun Canvas.draw3DArcTop(paint: Paint, cx: Float, cy: Float, radius: Float, innerRadius: Float, flipAngle: Float,
                        startAngle: Float, sweepAngle: Float, color: Int, dx: Float = 0f, dy: Float = 0f, sliceSpace: Float = 0f) {
    if (sweepAngle <= 0) {
        return
    }

    drawArc(paint, cx, cy, radius, flipAngle, innerRadius, startAngle, sweepAngle, color, dx, dy, sliceSpace)
}

/**
 * 绘制扇形
 *
 * @param cx 扇形的圆心X坐标
 * @param cy 扇形的圆心Y坐标
 * @param startAngle 扇形起始角度
 * @param sweepAngle 扇形角度
 * @param sliceSpace 各扇形直接的间隙，如果[sweepAngle] >= 360°，则此属性无效，如果动画绘制且最终绘制一个完整的圆，此值请传0，否则可能出现非预期错误
 */
fun Canvas.drawArc(paint: Paint, cx: Float, cy: Float, radius: Float, innerRadius: Float,
                   startAngle: Float, sweepAngle: Float, color: Int, dx: Float = 0f, dy: Float = 0f, sliceSpace: Float = 0f) {
    drawArc(paint, cx, cy, radius, 0f, innerRadius, startAngle, sweepAngle, color, dx, dy, sliceSpace)
}

/**
 * 绘制扇形
 *
 * @param cx 扇形的圆心X坐标
 * @param cy 扇形的圆心Y坐标
 * @param flipAngle 翻转角度，0°则和二维饼状图一致，90°则只能看到一个二维矩形.允许取值范围为0°~90°
 * @param startAngle 扇形起始角度
 * @param sweepAngle 扇形角度
 * @param sliceSpace 各扇形直接的间隙，如果[sweepAngle] >= 360°，则此属性无效，如果动画绘制且最终绘制一个完整的圆，此值请传0，否则可能出现非预期错误
 * @return true:实际进行了绘制，false：未执行绘制
 */
private fun Canvas.drawArc(paint: Paint, cx: Float, cy: Float, radius: Float, flipAngle: Float, innerRadius: Float,
                           startAngle: Float, sweepAngle: Float, color: Int, dx: Float = 0f, dy: Float = 0f, sliceSpace: Float = 0f): Boolean {
    if (sweepAngle <= 0) {
        return false
    }

    var addedDegrees = 0f
    var offsetRadius = 0f
    if (sweepAngle < 360) {
        // 求startAngle过圆心的直线平移sliceSpace / 2f后与圆的交点，得出交点与圆心连线的角度
        addedDegrees = 90f - acos(sliceSpace / 2f / radius).toDegrees
        if (addedDegrees * 2 >= sweepAngle) {
            return false
        }

        // 沿着偏移夹角的中轴线进行偏移
        // 计算扇形之间的间隙导致中心点偏移的半径
        offsetRadius = sliceSpace / 2f / sin(sweepAngle.toRadian / 2f)
        if (offsetRadius >= radius && sweepAngle <= 30) {
            // 间隙挤压导致饼状图不可见, 当sweepAngle趋近360°时，offsetRadius >= radius也会成立，
            // 因此还要求sweepAngle <= 30，一般情况下都是sweepAngle趋近0°时才会使offsetRadius >= radius成立
            return false
        }
    }

    var start = (startAngle + addedDegrees).to360Range
    var sweep = sweepAngle - addedDegrees * 2
    var radiusShort = radius * cos(flipAngle.toRadian)

    val centerX = cx + dx
    val centerY = cy + dy * cos(flipAngle.toRadian)

    val tempPath = ObjectPool.obtainPath()
    tempPath.reset()
    if (sweepAngle < 360) {
        // 计算偏移后的中心点
        if (innerRadius == 0f) {
            tempPath.moveTo(centerX + cos((startAngle + sweepAngle / 2f).toRadian) * offsetRadius,
                centerY + sin((startAngle + sweepAngle / 2f).toRadian) * offsetRadius * cos(flipAngle.toRadian))
            tempPath.arcTo(centerX - radius, centerY - radiusShort, centerX + radius, centerY + radiusShort, start, sweep, false)
        } else {
            val pathMeasure = ObjectPool.obtainPathMeasure()
            val tempPath2 = ObjectPool.obtainPath()
            val floatArray = ObjectPool.obtainFloatArray()

            tempPath2.arcTo(centerX - radius, centerY - radiusShort, centerX + radius, centerY + radiusShort, start, sweep, false)
            pathMeasure.setPath(tempPath2, false)
            if (pathMeasure.length > 0f) {
                pathMeasure.getPosTan(0f, floatArray, null)
                tempPath.moveTo(floatArray[0], floatArray[1])
                tempPath.arcTo(centerX - radius, centerY - radiusShort, centerX + radius, centerY + radiusShort, start, sweep, false)

                // 求startAngle过圆心的直线平移sliceSpace / 2f后与圆的交点，得出交点与圆心连线的角度
                addedDegrees = 90f - acos(sliceSpace / 2f / innerRadius).toDegrees
                if (addedDegrees * 2 >= sweepAngle) {
                    // 说明扇形中心点在内圆半径之外，此时直接绘制扇形即可
                    tempPath.lineTo(centerX + cos((startAngle + sweepAngle / 2f).toRadian) * offsetRadius,
                        centerY + sin((startAngle + sweepAngle / 2f).toRadian) * offsetRadius * cos(flipAngle.toRadian))
                } else {
                    start = (startAngle + addedDegrees).to360Range
                    sweep = sweepAngle - addedDegrees * 2
                    radiusShort = innerRadius * cos(flipAngle.toRadian)

                    tempPath2.reset()
                    tempPath2.arcTo(centerX - innerRadius, centerY - radiusShort, centerX + innerRadius, centerY + radiusShort, start, sweep, false)
                    pathMeasure.setPath(tempPath2, false)
                    if (pathMeasure.length == 0f) {
                        tempPath.lineTo(centerX + cos((startAngle + sweepAngle / 2f).toRadian) * offsetRadius,
                            centerY + sin((startAngle + sweepAngle / 2f).toRadian) * offsetRadius * cos(flipAngle.toRadian))
                    } else {
                        pathMeasure.getPosTan(pathMeasure.length, floatArray, null)
                        tempPath.lineTo(floatArray[0], floatArray[1])
                        tempPath.arcTo(centerX - innerRadius, centerY - radiusShort, centerX + innerRadius, centerY + radiusShort, start + sweep, -sweep, false)
                    }
                }
            }

            ObjectPool.recyclePathMeasure(pathMeasure)
            ObjectPool.recyclePath(tempPath2)
            ObjectPool.recycleFloatArray(floatArray)
        }
    } else {
        tempPath.addOval(centerX - radius, centerY - radiusShort, centerX + radius, centerY + radiusShort, Path.Direction.CW)
        if (innerRadius > 0) {
            radiusShort = innerRadius * cos(flipAngle.toRadian)
            tempPath.addOval(centerX - innerRadius, centerY - radiusShort, centerX + innerRadius, centerY + radiusShort, Path.Direction.CCW)
        }
    }

    paint.color = color
    paint.style = Paint.Style.FILL
    drawPath(tempPath, paint)

    ObjectPool.recyclePath(tempPath)

    return true
}